<template>
  <div style="position: relative">
    <div :id="mapId" class="ct-map-container"/>
    <div class="controls">
      <slot></slot>
    </div>
  </div>
</template>

<script>
import 'maptalks/dist/maptalks.css';
import * as maptalks from 'maptalks';
import {Coordinate} from 'maptalks';
import {
  create4326Layer,
  createBDBaseLayer,
  createBDSatelliteLayer,
  createBDTrafficLayer,
  createGDBaseLayer,
  createGDSatelliteLayer,
  createGDTrafficLayer,
  createXTMapAndLayer,
  set4326SpatialReference,
  setBDSpatialReference,
  setGDSpatialReference,
  showBDBase,
  showBDSatellite,
  showBDTraffic,
  showGDBase,
  showGDSatellite,
  showGDTraffic,
} from '../../api/layerConvert';
import CtMapUtils from "../../api/ctMap";

export default {
  name: 'ctMap',
  components: {
    createXTMapAndLayer,
    showGDBase,
    showBDBase,
    showBDTraffic,
    showBDSatellite,
    showGDSatellite,
    showGDTraffic,
    setGDSpatialReference,
    setBDSpatialReference,
    set4326SpatialReference,
  },
  props: {
    mapId: {
      type: String,
      default: null,
    },
    ctScaleControl: {
      type: Boolean,
      default: false,
    },
    ctOverview: {
      type: Boolean,
      default: false,
    },
    draggable: {
      type: Boolean,
      default: true,
    },
    dragPitch: {
      type: Boolean,
      default: false,
    },
    dragRotate: {
      type: Boolean,
      default: false,
    },
    dragRotatePitch: {
      type: Boolean,
      default: false,
    },
    ctZoom: {
      type: Number,
      default() {
        return 14;
      },
    },
    ctCenter: {
      type: Array,
      default() {
        return [126.626236, 45.767623]
      },
    },
    ctZoomControl: {
      type: Boolean,
      default() {
        return false;
      },
    },
    // 坐标参考系
    crs: {
      type: String,
      default() {
        // gaode,baidu,wgs84,4326
        return 'gaode';
      },
    },
    dbClick: {
      type: Boolean,
      default() {
        return false;
      },
    },
    /**
     * 'zoomend,moving,moveend,click'
     */
    mapListens: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  data: () => ({
    map: {},
    firstLayer: null,
    mapStatus: {},
    // 图层
    gdBase: null,
    bdBase: null,
    wgs84Base: null,
    bdTrafficLayer: null,
    gdTrafficLayer: null,
    bdSatelliteLayer: null,
    gdSatelliteLayer: null,
    // 图层 查询 容器
    ctExtendLayers: [], // 扩展图层
    ctTotalLayersMap: new Map(),// 全部图层  map 结构
    ctTotalLayers: [], // 全部图层
  }),
  beforeMount() {
    let _this = this
    if (!this.mapId) {
      console.error(' missing mapId attribute')
    }
    this.$nextTick(() => {
      this.initMap(this.mapId, this.initConfig());
      // 默认新建一个图层，命名为 firstLayer
      this.firstLayer = new maptalks.VectorLayer('firstLayer', null, {zIndex: 1}).addTo(this.map);
      if (this.mapListens.length > 0) {
        let s = this.mapListens.toString().replaceAll(',', ' ')
        // 地图监听事件 'zoomend moving moveend'
        this.map.on(s, (param) => {
          _this.getStatus(param)
        });
      }
      let MapUtil = {
        Map: this.map,
        CityJSON: null,
        Layer: this.firstLayer,
        CtMapUtils: CtMapUtils,
        systemLayerArray: this.ctTotalLayers,
        systemLayerMap: this.ctTotalLayersMap
      }
      this.$emit('mapInitCompleted', MapUtil)
    });
  },
  mounted() {
  },
  methods: {
    getStatus(param) {
      switch (param.type) {
        case 'click':
          let clickPoint = param.coordinate.toFixed(5).toArray();
          this.$emit('click', param, clickPoint);
          break
        case 'zoomend':
          let zoomFrom = param.from;
          let zoomTo = param.to;
          this.$emit('zoomend', param, zoomFrom, zoomTo);
          break
        case 'moving':
          this.$emit('moving', param);
          break
        case 'moveend':
          let map = param.target;
          let center = map.getCenter().toFixed(5).toArray();
          let zoom = map.getZoom();
          this.$emit('moveend', param, center, zoom);
          break
        case 'spatialreferencechange':
          this.$emit('spatialreferencechange', param, null, null);
          break
        case 'resize':
          this.$emit('resize', param.target.getSize(), null, null);
          break
        case 'dblclick':
          this.$emit('dblclick', param);
          break
        default :
          this.$emit('unknownEvent', param, null, null);
          break
      }
      const map = this.map
      const extent = map.getExtent();
      const ex = [
        '{',
        `xmin:${extent.xmin.toFixed(5)}`,
        `, ymin:${extent.ymin.toFixed(5)}`,
        `, xmax:${extent.xmax.toFixed(5)}`,
        `, ymax:${extent.xmax.toFixed(5)}`,
        '}',
      ].join('');
      const center = map.getCenter();
      this.mapStatus = {
        Center: `[${[center.x.toFixed(5), center.y.toFixed(5)].join()}]`,
        Extent: `${ex}`,
        Size: `${map.getSize()
          .toArray()
          .join()}`,
        Zoom: `${map.getZoom()}`,
        MinZoom: `${map.getMinZoom()}`,
        MaxZoom: `${map.getMaxZoom()}`,
        Projection: `${map.getProjection().code}`,
      };
      this.$emit('mapStatus', this.mapStatus);
    },
    //创建图层
    initLayers() {
      // 高德 图层
      this.gdBase = createGDBaseLayer();
      this.gdTrafficLayer = createGDTrafficLayer();
      this.gdSatelliteLayer = createGDSatelliteLayer();
      // 百度 图层
      this.bdBase = createBDBaseLayer();
      this.bdTrafficLayer = createBDTrafficLayer();
      this.bdSatelliteLayer = createBDSatelliteLayer();
      // wgs84
      this.wgs84Base = create4326Layer();
      // 隐藏图层
      this.gdBase.hide()
      this.bdBase.hide()
      this.wgs84Base.hide()
      this.bdTrafficLayer.hide()
      this.gdTrafficLayer.hide()
      this.bdSatelliteLayer.hide()
      this.gdSatelliteLayer.hide()
      // 创建 图层 容器
      this.ctTotalLayers = [this.gdBase, this.bdBase, this.wgs84Base, this.bdTrafficLayer, this.gdTrafficLayer, this.bdSatelliteLayer, this.gdSatelliteLayer]
      this.ctTotalLayersMap.set('gdBase', this.gdBase)
      this.ctTotalLayersMap.set('bdBase', this.bdBase)
      this.ctTotalLayersMap.set('wgs84Base', this.wgs84Base)
      this.ctTotalLayersMap.set('bdTrafficLayer', this.bdTrafficLayer)
      this.ctTotalLayersMap.set('gdTrafficLayer', this.gdTrafficLayer)
      this.ctTotalLayersMap.set('bdSatelliteLayer', this.bdSatelliteLayer)
      this.ctTotalLayersMap.set('gdSatelliteLayer', this.gdSatelliteLayer)
      // 返回 扩展图层 （定义：除了底图之外的都为扩展图层）
      this.ctExtendLayers = [this.bdTrafficLayer, this.gdTrafficLayer, this.bdSatelliteLayer, this.gdSatelliteLayer]
      return this.ctExtendLayers
    },
    initMap(mapId, config) {
      this.map = new maptalks.Map(mapId, config);
      let layers = this.initLayers();
      this.map.addLayer(layers)
      // gaode,baidu,wgs84
      switch (this.crs.toLowerCase()) {
        case 'gaode':
          setGDSpatialReference(this.map, this.ctTotalLayers, this.gdBase)
          break
        case 'baidu':
          setBDSpatialReference(this.map, this.ctTotalLayers, this.bdBase)
          break
        case 'wgs84':
          set4326SpatialReference(this.map, this.ctTotalLayers, this.wgs84Base)
          break
        case '4326':
          set4326SpatialReference(this.map, this.ctTotalLayers, this.wgs84Base)
          break
        default:
          break
      }
      return this.map
    },
    initConfig() {
      return {
        center: new Coordinate(this.ctCenter),
        zoom: this.ctZoom, // 初始 zoom
        maxZoom: 18,
        minZoom: 5,
        draggable: this.draggable,
        dragPitch: this.dragPitch,
        dragRotate: this.dragRotate,
        dragRotatePitch: this.dragRotatePitch,
        attribution: true,
        zoomControl: this.ctZoomControl,
        scaleControl: this.ctScaleControl,
        overviewControl: this.ctOverview,
        doubleClickZoom: this.dbClick,
      }
    },
  },
  computed: {}
};
</script>
<style scoped>
.ct-map-container {
  height: 100%;
  width: 100%;
}

.controls {
  position: absolute;
  display: flex;
  top: 10px;
  left: 10px;
}

/deep/ .maptalks-attribution span a {
  display: none;
}

</style>

